/*
 * Copyright (C) 2013 Andreas Stuetz <andreas.stuetz@gmail.com>
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.lv.common.widget.tab;

import android.annotation.SuppressLint;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.LinearGradient;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.RectF;
import android.graphics.Shader;
import android.graphics.Typeface;
import android.os.Build;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.util.TypedValue;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver.OnGlobalLayoutListener;
import android.widget.HorizontalScrollView;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.TextView;

import androidx.viewpager.widget.ViewPager;
import androidx.viewpager2.widget.ViewPager2;

import com.lv.common.R;

import java.util.List;
import java.util.Locale;

/**
 * 作者： ygx
 * 创建日期：${DATE} ${TIME}
 * 签名： 天行健，君子以自强不息；地势坤，君子以厚德载物。
 * _              _           _     _   ____  _             _ _
 * / \   _ __   __| |_ __ ___ (_) __| | / ___|| |_ _   _  __| (_) ___
 * / _ \ | '_ \ / _` | '__/ _ \| |/ _` | \___ \| __| | | |/ _` | |/ _ \
 * / ___ \| | | | (_| | | | (_) | | (_| |  ___) | |_| |_| | (_| | | (_) |
 * /_/   \_\_| |_|\__,_|_|  \___/|_|\__,_| |____/ \__|\__,_|\__,_|_|\___/
 * <p>
 * You never know what you can do until you try !
 * ----------------------------------------------------------------
 * <com.lv.suyiyong.owner.widget.tab.PagerSlidingNewTabStrip
 * android:id="@+id/psts_indicator"
 * android:layout_width="wrap_content"
 * android:background="@color/white"
 * android:layout_height="45dp"
 * android:layout_centerHorizontal="true"
 * android:textColor="@color/color_242424"
 * android:textSize="16sp"
 * app:pstsDividerColor="@android:color/transparent"
 * app:pstsIndicatorColor="@android:color/transparent"
 * app:pstsIndicatorHeight="6dp"
 * app:pstsTabPaddingLeftRight="23dp"
 * app:pstsTextColorSelect="@color/color_242424"
 * app:pstsTextSizeSelect="16sp"
 * app:pstsUnderlineHeight="0dp"
 * app:ygxIndicatorPaddingBottom="11dp"
 * app:ygxIndicatorRadus="4dp"
 * app:ygxIndicatorWith="38dp"
 * app:ygxSelectedBold="true"
 * app:ygxShowMyTag="true"
 * app:ygxShowTag="false" />
 */

public class ViewPager2SlidingTab extends HorizontalScrollView {
    private static final String TAG = "PagerSlidingTabStrip";

    public interface IconTabProvider {
        int getPageIconResId(int position);
    }

    // @formatter:off
    private static final int[] ATTRS = new int[]{
            android.R.attr.textSize,
            android.R.attr.textColor
    };
    // @formatter:on

    private LinearLayout.LayoutParams defaultTabLayoutParams;

    private LinearLayout.LayoutParams expandedTabLayoutParams;
    private final PageListener pageListener = new PageListener();

    public ViewPager2.OnPageChangeCallback delegatePageListener;
    private LinearLayout tabsContainer;

    private ViewPager2 pager;
    private int tabCount;

    private int currentPosition = 0;

    private float currentPositionOffset = 0f;
    private Paint rectPaint;

    private Paint dividerPaint;
    private int indicatorColor = 0xFF666666;

    private int underlineColor = 0x1A000000;
    private int dividerColor = 0x1A000000;
    private boolean shouldExpand = false;
    private boolean ygxSelectedBold = true;//是否选中加粗
    private boolean ygxTextBold = false;//非选中是否加粗
    private boolean ygxShowTag = false;//是否显示右上角标记
    private boolean ygxShowMyTag = false;//是否显示自定义指示器
    private int mRadus = 0;//圆角
    private boolean ygxIndicatorIsCanter = false;//是否居中显示自定义指示器
    private String indicatorStartColor = "#ffffff";
    private String indicatorEndColor = "#ffffff";
    private boolean textAllCaps = true;
    private int scrollOffset = 52;

    private int indicatorHeight = 8;
    private int underlineHeight = 2;
    private int dividerPadding = 12;
    private int tabPadding = 24;
    private int dividerWidth = 1;
    private int tabTextSize = 12;
    private int ygxIndicatorPaddingBottom = 0;

    private int tabTextColor = 0xFF666666;
    private Typeface tabTypeface = null;
    private int tabTypefaceStyle = Typeface.BOLD;
    private int lastScrollX = 0;

    private int tabBackgroundResId = R.drawable.pagerslidingtabstrip_tab;

    private Locale locale;

    private int tabTextSizeSelect = tabTextSize;
    private int tabTextColorSelect = tabTextColor;

    private int indicatorLineSpace = 0;
    private int ygxIndicatorWith = 0;//设置自定义指示器的宽度
    private int paddingLeft = 0;
    private int paddingRight = 0;
    //shouldExpand=true才可以设置此属性：导航滑条跟字体长度相同。
    private boolean indicatorWidthFollowText;
    //导航滑条跟字体长度的比例
    private float indicatorWidthScale = 1.0f;
    private RectF mIndicatorMyRect;//重新定义的指示器

    private RectF mIndicatorRect;//原来的指示器
    private Paint mPaint;

    public ViewPager2SlidingTab(Context context) {
        this(context, null);
    }

    public ViewPager2SlidingTab(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public ViewPager2SlidingTab(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);

        mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
        mPaint.setStyle(Style.FILL);
        mIndicatorRect = new RectF();
        mIndicatorMyRect = new RectF();
        setFillViewport(true);
        setWillNotDraw(false);

        DisplayMetrics dm = getResources().getDisplayMetrics();

        scrollOffset = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, scrollOffset, dm);
        indicatorHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorHeight, dm);
        underlineHeight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, underlineHeight, dm);
        dividerPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerPadding, dm);
        tabPadding = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, tabPadding, dm);
        dividerWidth = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dividerWidth, dm);
        tabTextSize = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_SP, tabTextSize, dm);
        indicatorLineSpace = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, indicatorLineSpace, dm);
        paddingLeft = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paddingLeft, dm);
        paddingRight = (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, paddingRight, dm);

        // get system attrs (android:textSize and android:textColor)

        TypedArray a = context.obtainStyledAttributes(attrs, ATTRS);

        tabTextSize = a.getDimensionPixelSize(0, tabTextSize);
        //noinspection ResourceType
        tabTextColor = a.getColor(1, tabTextColor);

        a.recycle();

        // get custom attrs

        a = context.obtainStyledAttributes(attrs, R.styleable.PagerSlidingTabStrip);
        indicatorStartColor = a.getString(R.styleable.PagerSlidingTabStrip_ygxIndicatorStartColor);
        indicatorEndColor = a.getString(R.styleable.PagerSlidingTabStrip_ygxIndicatorEndColor);

        indicatorColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsIndicatorColor, indicatorColor);
        underlineColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsUnderlineColor, underlineColor);
        dividerColor = a.getColor(R.styleable.PagerSlidingTabStrip_pstsDividerColor, dividerColor);
        // @formatter:off
        indicatorHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorHeight, indicatorHeight);
        underlineHeight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsUnderlineHeight, underlineHeight);
        // @formatter:on
        dividerPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsDividerPadding, dividerPadding);
        tabPadding = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTabPaddingLeftRight, tabPadding);
        tabBackgroundResId = a.getResourceId(R.styleable.PagerSlidingTabStrip_pstsTabBackground, tabBackgroundResId);
        shouldExpand = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsShouldExpand, shouldExpand);
        scrollOffset = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsScrollOffset, scrollOffset);
        textAllCaps = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsTextAllCaps, textAllCaps);
        tabTextSizeSelect = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsTextSizeSelect, tabTextSize);
        tabTextColorSelect = a.getColor(R.styleable.PagerSlidingTabStrip_pstsTextColorSelect, tabTextColor);
        // @formatter:off
        indicatorLineSpace = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsIndicatorLineSpace, indicatorLineSpace);
        ygxIndicatorWith = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_ygxIndicatorWith, ygxIndicatorWith);
//        ygxIndicatorWith = dp2px(ygxIndicatorWith);
        // @formatter:on
        paddingLeft = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsPaddingLeft, paddingLeft);
        paddingRight = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_pstsPaddingRight, paddingRight);
        ygxIndicatorPaddingBottom = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_ygxIndicatorPaddingBottom, ygxIndicatorPaddingBottom);
        indicatorWidthFollowText = a.getBoolean(R.styleable.PagerSlidingTabStrip_pstsIndicatorWidthFollowText, indicatorWidthFollowText);
        indicatorWidthScale = a.getFloat(R.styleable.PagerSlidingTabStrip_pstsIndicatorWidthScale, indicatorWidthScale);
        ygxSelectedBold = a.getBoolean(R.styleable.PagerSlidingTabStrip_ygxSelectedBold, ygxSelectedBold);
        ygxTextBold = a.getBoolean(R.styleable.PagerSlidingTabStrip_ygxTextBold, ygxTextBold);

        ygxShowTag = a.getBoolean(R.styleable.PagerSlidingTabStrip_ygxShowTag, ygxShowTag);
        ygxShowMyTag = a.getBoolean(R.styleable.PagerSlidingTabStrip_ygxShowMyTag, ygxShowMyTag);
        ygxIndicatorIsCanter = a.getBoolean(R.styleable.PagerSlidingTabStrip_ygxIndicatorIsCanter, ygxIndicatorIsCanter);
        mRadus = a.getDimensionPixelSize(R.styleable.PagerSlidingTabStrip_ygxIndicatorRadus, mRadus);
        a.recycle();

        rectPaint = new Paint();
        rectPaint.setAntiAlias(true);
        rectPaint.setStyle(Style.FILL);

        dividerPaint = new Paint();
        dividerPaint.setAntiAlias(true);
        dividerPaint.setStrokeWidth(dividerWidth);

        defaultTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT);
        expandedTabLayoutParams = new LinearLayout.LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT, 1.0f);

        tabsContainer = new LinearLayout(context);
        tabsContainer.setOrientation(LinearLayout.HORIZONTAL);
        tabsContainer.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        updateContainer();
        addView(tabsContainer);

        if (locale == null) {
            locale = getResources().getConfiguration().locale;
        }
    }

    public void setViewPager(ViewPager2 pager, List<String> titles) {
        this.pager = pager;

        if (pager.getAdapter() == null) {
            throw new IllegalStateException("ViewPager does not have adapter instance.");
        }

        pager.registerOnPageChangeCallback(pageListener);

        notifyDataSetChanged(titles);
    }

    public void setOnPageChangeListener(ViewPager2.OnPageChangeCallback listener) {
        this.delegatePageListener = listener;
    }

    public void notifyDataSetChanged(List<String> titles) {

        tabsContainer.removeAllViews();

        tabCount = pager.getAdapter().getItemCount();

        for (int i = 0; i < tabCount; i++) {

            if (pager.getAdapter() instanceof IconTabProvider) {
                addIconTab(i, ((IconTabProvider) pager.getAdapter()).getPageIconResId(i));
            } else {
                addTextTab(i, titles.get(i));
            }
        }

        updateTabStyles();

        getViewTreeObserver().addOnGlobalLayoutListener(new OnGlobalLayoutListener() {

            @SuppressWarnings("deprecation")
            @SuppressLint("NewApi")
            @Override
            public void onGlobalLayout() {

                if (Build.VERSION.SDK_INT < Build.VERSION_CODES.JELLY_BEAN) {
                    getViewTreeObserver().removeGlobalOnLayoutListener(this);
                } else {
                    getViewTreeObserver().removeOnGlobalLayoutListener(this);
                }

                currentPosition = pager.getCurrentItem();
                scrollToChild(currentPosition, 0);
            }
        });

    }

    private void addTextTab(final int position, String title) {

        TextView tab = new TextView(getContext());
        tab.setText(title);
        tab.setGravity(Gravity.CENTER);
        tab.setSingleLine();
        tab.getPaint().setFakeBoldText(ygxTextBold);
        addTab(position, tab);
    }

    private void addIconTab(final int position, int resId) {
        ImageButton tab = new ImageButton(getContext());
        tab.setImageResource(resId);

        addTab(position, tab);
    }

    private void addTab(final int position, View tab) {
        tab.setFocusable(true);
        tab.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                pager.setCurrentItem(position);
            }
        });

        tab.setPadding(tabPadding, 0, tabPadding, 0);
        tabsContainer.addView(tab, position, shouldExpand ? expandedTabLayoutParams : defaultTabLayoutParams);
    }

    private void updateTabStyles() {

        for (int i = 0; i < tabCount; i++) {

            View v = tabsContainer.getChildAt(i);

            v.setBackgroundResource(tabBackgroundResId);

            if (v instanceof TextView) {
                int currentItem = pager.getCurrentItem();

                TextView tab = (TextView) v;
                int textSize = currentItem == i ? tabTextSizeSelect : tabTextSize;
                tab.setTextSize(TypedValue.COMPLEX_UNIT_PX, textSize);
                // tab.setTypeface(tabTypeface, tabTypefaceStyle);
                // tab.setTextColor(tabTextColor);
                int textColor = currentItem == i ? tabTextColorSelect : tabTextColor;
                tab.setTextColor(textColor);

                //选中文字加粗
                TextPaint tp = tab.getPaint();
                if (ygxTextBold) {
                    tp.setFakeBoldText(true);
                } else {
                    if (ygxSelectedBold && currentItem == i) {
                        tp.setFakeBoldText(true);
                    } else {
                        tp.setFakeBoldText(false);
                    }
                }
//                if (ygxSelectedBold && currentItem == i) {
//                    tp.setFakeBoldText(true);
//                }
//                if (ygxSelectedBold) {
//                tp.setFakeBoldText(currentItem == i);
//                }

                // setAllCaps() is only available from API 14, so the upper case is made manually if we are on a
                // pre-ICS-build
                if (textAllCaps) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH) {
                        tab.setAllCaps(true);
                    } else {
                        tab.setText(tab.getText().toString().toUpperCase(locale));
                    }
                }
            }
        }
    }

    private void updateContainer() {
        tabsContainer.setPadding(paddingLeft, 0, paddingRight, 0);
    }

    private void scrollToChild(int position, int offset) {

        if (tabCount == 0) {
            return;
        }
        View childAt = tabsContainer.getChildAt(position);
        int newScrollX = childAt.getLeft() + offset - childAt.getWidth();

        if (position > 0 || offset > 0) {
            newScrollX -= scrollOffset;
        } else if (position == 0) {
            newScrollX = 0;
        }
//
        if (newScrollX != lastScrollX) {
            lastScrollX = newScrollX;
            scrollTo(newScrollX, 0);
        }
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);

        if (isInEditMode() || tabCount == 0) {
            return;
        }

        final int height = getHeight();

        // draw indicator line

        rectPaint.setColor(indicatorColor);

        // default: line below current tab
        View currentTab = tabsContainer.getChildAt(currentPosition);
        float lineLeft;
        float lineRight;
        if (indicatorWidthFollowText && shouldExpand) {
            int textLeft = currentTab.getLeft() + (currentTab.getWidth() - getCurrentPositionTextWidth()) / 2;
            int textRight = textLeft + getCurrentPositionTextWidth();
            lineLeft = textLeft;
            lineRight = textRight;
        } else {
            lineLeft = currentTab.getLeft();
            lineRight = currentTab.getRight();
        }

        // if there is an offset, start interpolating left and right coordinates between current and next tab
        if (currentPositionOffset > 0f && currentPosition < tabCount - 1) {

            View nextTab = tabsContainer.getChildAt(currentPosition + 1);
            final float nextTabLeft;
            final float nextTabRight;
            if (indicatorWidthFollowText && shouldExpand) {
                int nextTextLeft = nextTab.getLeft() + (nextTab.getRight() - currentTab.getRight() - getNextPositionTextWidth()) / 2;
                int nextTextRight = nextTextLeft + getNextPositionTextWidth();
                nextTabLeft = nextTextLeft;
                nextTabRight = nextTextRight;
            } else {
                nextTabLeft = nextTab.getLeft();
                nextTabRight = nextTab.getRight();
            }
            lineLeft = (currentPositionOffset * nextTabLeft + (1f - currentPositionOffset) * lineLeft);
            lineRight = (currentPositionOffset * nextTabRight + (1f - currentPositionOffset) * lineRight);


        }

        //画文字右上角的tag
        if (ygxShowTag) {
            int i1 = tabsContainer.getChildAt(currentPosition).getWidth() - getCurrentPositionTextWidth();
            float mIndicatorCenterX = lineRight - i1 / 2;
            mIndicatorRect.left = mIndicatorCenterX - dp2px(10) / 2;
            mIndicatorRect.right = mIndicatorCenterX + dp2px(10) / 2;
            mIndicatorRect.top = dp2px(12);
            mIndicatorRect.bottom = dp2px(22);
            LinearGradient tabShader = new LinearGradient(mIndicatorRect.left, mIndicatorRect.bottom, mIndicatorRect.right, mIndicatorRect.top, Color.parseColor("#ffffff"), Color.parseColor("#EF7B4A"), Shader.TileMode.CLAMP);
            mPaint.setShader(tabShader);
            canvas.drawRoundRect(mIndicatorRect, dp2px(10), dp2px(10), mPaint);
        }
        int i1 = tabsContainer.getChildAt(currentPosition).getWidth();
        float mIndicatorCenterX = lineRight - i1 / 2;
        if (ygxShowMyTag) {
//            float mIndicatorCenterX = lineRight - i1 / 2;
            if (ygxIndicatorWith == 0) {
                mIndicatorRect.left = lineLeft + indicatorLineSpace;
                mIndicatorRect.right = lineRight - indicatorLineSpace;
            } else {
                mIndicatorRect.left = mIndicatorCenterX - ygxIndicatorWith / 2;
                mIndicatorRect.right = mIndicatorCenterX + ygxIndicatorWith / 2;
            }
            mIndicatorRect.top = height - indicatorHeight - ygxIndicatorPaddingBottom;
            mIndicatorRect.bottom = height - ygxIndicatorPaddingBottom;
            LinearGradient tabShader = new LinearGradient(mIndicatorRect.left, 0, mIndicatorRect.right, 0, Color.parseColor(indicatorStartColor), Color.parseColor(indicatorEndColor), Shader.TileMode.CLAMP);
            mPaint.setShader(tabShader);
            canvas.drawRoundRect(mIndicatorRect, dp2px(mRadus), dp2px(mRadus), mPaint);
        }

        // @formatter:off
        if (ygxIndicatorIsCanter) {//tab指示器 居中
            if (ygxIndicatorWith == 0) {
                canvas.drawRoundRect(lineLeft + indicatorLineSpace, (height - indicatorHeight) / 2, lineRight - indicatorLineSpace, height - (height - indicatorHeight) / 2, mRadus, mRadus, rectPaint);
            } else {
                canvas.drawRoundRect(mIndicatorCenterX - ygxIndicatorWith / 2, (height - indicatorHeight) / 2, mIndicatorCenterX + ygxIndicatorWith / 2, height - (height - indicatorHeight) / 2, mRadus, mRadus, rectPaint);
            }
        } else {
            if (ygxIndicatorWith == 0) {
                canvas.drawRoundRect(lineLeft + indicatorLineSpace, height - indicatorHeight, lineRight - indicatorLineSpace, height, mRadus, mRadus, rectPaint);
            } else {
                canvas.drawRoundRect(mIndicatorCenterX - ygxIndicatorWith / 2, height - indicatorHeight, mIndicatorCenterX + ygxIndicatorWith / 2, height, mRadus, mRadus, rectPaint);
            }

        }
//        canvas.drawRoundRect(lineLeft + indicatorLineSpace, height - indicatorHeight, lineRight - indicatorLineSpace, height, mRadus, mRadus, rectPaint);

//        canvas.drawRoundRect(0, height - underlineHeight, tabsContainer.getWidth(), height, mRadus, mRadus, rectPaint);
        // @formatter:on

        // draw underline

        rectPaint.setColor(underlineColor);
        canvas.drawRoundRect(0, height - underlineHeight, tabsContainer.getWidth(), height, mRadus, mRadus, rectPaint);
        // draw divider
        dividerPaint.setColor(dividerColor);
        for (int i = 0; i < tabCount - 1; i++) {
            View tab = tabsContainer.getChildAt(i);
            canvas.drawLine(tab.getRight(), dividerPadding, tab.getRight(), height - dividerPadding, dividerPaint);
        }


    }

    private int dp2px(int dp) {
        return (int) TypedValue.applyDimension(
                TypedValue.COMPLEX_UNIT_DIP, dp, getContext().getResources().getDisplayMetrics()
        );
    }


    private class PageListener extends ViewPager2.OnPageChangeCallback {

        @Override
        public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) {

            currentPosition = position;
            currentPositionOffset = positionOffset;
            if (tabsContainer == null || tabsContainer.getChildCount() == 0) {
                return;
            }
            scrollToChild(position, Math.round(positionOffset * tabsContainer.getChildAt(position).getWidth()));

            invalidate();

            if (delegatePageListener != null) {
                delegatePageListener.onPageScrolled(position, positionOffset, positionOffsetPixels);
            }
        }

        @Override
        public void onPageScrollStateChanged(int state) {
            if (state == ViewPager.SCROLL_STATE_IDLE) {
                scrollToChild(pager.getCurrentItem(), 0);
            }

            if (delegatePageListener != null) {
                delegatePageListener.onPageScrollStateChanged(state);
            }
        }

        @Override
        public void onPageSelected(int position) {
            updateTabStyles();
            if (delegatePageListener != null) {
                delegatePageListener.onPageSelected(position);
            }
        }

    }

    public void setIndicatorColor(int indicatorColor) {
        this.indicatorColor = indicatorColor;
        invalidate();
    }

    public void setIndicatorColorResource(int resId) {
        this.indicatorColor = getResources().getColor(resId);
        invalidate();
    }

    public int getIndicatorColor() {
        return this.indicatorColor;
    }

    public void setIndicatorHeight(int indicatorLineHeightPx) {
        this.indicatorHeight = indicatorLineHeightPx;
        invalidate();
    }

    public int getIndicatorHeight() {
        return indicatorHeight;
    }

    public void setUnderlineColor(int underlineColor) {
        this.underlineColor = underlineColor;
        invalidate();
    }

    public void setUnderlineColorResource(int resId) {
        this.underlineColor = getResources().getColor(resId);
        invalidate();
    }

    public int getUnderlineColor() {
        return underlineColor;
    }

    public void setDividerColor(int dividerColor) {
        this.dividerColor = dividerColor;
        invalidate();
    }

    public void setDividerColorResource(int resId) {
        this.dividerColor = getResources().getColor(resId);
        invalidate();
    }

    public int getDividerColor() {
        return dividerColor;
    }

    public void setUnderlineHeight(int underlineHeightPx) {
        this.underlineHeight = underlineHeightPx;
        invalidate();
    }

    public int getUnderlineHeight() {
        return underlineHeight;
    }

    public void setDividerPadding(int dividerPaddingPx) {
        this.dividerPadding = dividerPaddingPx;
        invalidate();
    }

    public int getDividerPadding() {
        return dividerPadding;
    }

    public void setScrollOffset(int scrollOffsetPx) {
        this.scrollOffset = scrollOffsetPx;
        invalidate();
    }

    public int getScrollOffset() {
        return scrollOffset;
    }

    public void setShouldExpand(boolean shouldExpand) {
        this.shouldExpand = shouldExpand;
        requestLayout();
    }

    public boolean getShouldExpand() {
        return shouldExpand;
    }

    public boolean isTextAllCaps() {
        return textAllCaps;
    }

    public void setAllCaps(boolean textAllCaps) {
        this.textAllCaps = textAllCaps;
    }

    public void setTextSize(int textSizePx) {
        this.tabTextSize = textSizePx;
        updateTabStyles();
    }

    public int getTextSize() {
        return tabTextSize;
    }

    public void setTextColor(int textColor) {
        this.tabTextColor = textColor;
        updateTabStyles();
    }

    public void setTextColorResource(int resId) {
        this.tabTextColor = getResources().getColor(resId);
        updateTabStyles();
    }

    public int getTextColor() {
        return tabTextColor;
    }

    public void setTypeface(Typeface typeface, int style) {
        this.tabTypeface = typeface;
        this.tabTypefaceStyle = style;
        updateTabStyles();
    }

    public void setTabBackground(int resId) {
        this.tabBackgroundResId = resId;
    }

    public int getTabBackground() {
        return tabBackgroundResId;
    }

    public void setTabPaddingLeftRight(int paddingPx) {
        this.tabPadding = paddingPx;
        updateTabStyles();
    }

    public int getTabPaddingLeftRight() {
        return tabPadding;
    }

    public int getTabTextColorSelect() {
        return tabTextColorSelect;
    }

    public void setTabTextColorSelect(int tabTextColorSelect) {
        this.tabTextColorSelect = tabTextColorSelect;
        updateTabStyles();
    }

    public int getTabTextSizeSelect() {
        return tabTextSizeSelect;
    }

    /**
     * 设置选中标签的字体大小
     *
     * @param tabTextSizeSelect 字体大小(sp)
     */
    public void setTabTextSizeSelect(int tabTextSizeSelect) {
        this.tabTextSizeSelect = tabTextSizeSelect;
        updateTabStyles();
    }

    /**
     * 获取页签下划线的间距
     *
     * @return 间距大小(px)
     */
    public int getIndicatorLineSpace() {
        return indicatorLineSpace;
    }

    /**
     * 设置页签下划线间距
     *
     * @param indicatorLineSpace 下划线间距(px)
     */
    public void setIndicatorLineSpace(int indicatorLineSpace) {
        this.indicatorLineSpace = indicatorLineSpace;
        invalidate();
    }

    /**
     * 获取标签容器左侧间距
     *
     * @return 间距(px)
     */
    @Override
    public int getPaddingLeft() {
        return paddingLeft;
    }

    /**
     * 设置容器左侧间距
     *
     * @param paddingLeft 间距(px)
     */
    public void setPaddingLeft(int paddingLeft) {
        this.paddingLeft = paddingLeft;

        updateContainer();
    }

    /**
     * 获取标签容器右侧间距
     *
     * @return 间距(px)
     */
    @Override
    public int getPaddingRight() {
        return paddingRight;
    }

    /**
     * 设置容器右侧间距
     *
     * @param paddingRight 间距(px)
     */
    public void setPaddingRight(int paddingRight) {
        this.paddingRight = paddingRight;

        updateContainer();
    }

    /**
     * 获取当前tab文本宽度
     *
     * @return
     */
    private int getCurrentPositionTextWidth() {
        int textPaintWidth = 0;
        if (tabCount > currentPosition) {
            View v = tabsContainer.getChildAt(currentPosition);
            if (v != null && v instanceof TextView) {
                TextPaint textPaint = ((TextView) v).getPaint();
                if (!TextUtils.isEmpty(((TextView) v).getText())) {
                    String text = ((TextView) v).getText().toString();
                    textPaintWidth = (int) textPaint.measureText(text);
                }
            }
        }
        return (int) (textPaintWidth * indicatorWidthScale);
    }

    /**
     * 获取下一个tab文本宽度
     *
     * @return
     */
    private int getNextPositionTextWidth() {
        int textPaintWidth = 0;
        if (currentPosition < tabCount - 1) {
            View v = tabsContainer.getChildAt(currentPosition + 1);
            if (v != null && v instanceof TextView) {
                TextPaint textPaint = ((TextView) v).getPaint();
                if (!TextUtils.isEmpty(((TextView) v).getText())) {
                    String text = ((TextView) v).getText().toString();
                    textPaintWidth = (int) textPaint.measureText(text);
                }
            }
        }
        return (int) (textPaintWidth * indicatorWidthScale);
    }

    @Override
    public void onRestoreInstanceState(Parcelable state) {
        SavedState savedState = (SavedState) state;
        super.onRestoreInstanceState(savedState.getSuperState());
        currentPosition = savedState.currentPosition;
        updateTabStyles();
        requestLayout();
    }

    @Override
    public Parcelable onSaveInstanceState() {
        Parcelable superState = super.onSaveInstanceState();
        SavedState savedState = new SavedState(superState);
        savedState.currentPosition = currentPosition;
        return savedState;
    }

    static class SavedState extends BaseSavedState {
        int currentPosition;

        public SavedState(Parcelable superState) {
            super(superState);
        }

        private SavedState(Parcel in) {
            super(in);
            currentPosition = in.readInt();
        }

        @Override
        public void writeToParcel(Parcel dest, int flags) {
            super.writeToParcel(dest, flags);
            dest.writeInt(currentPosition);
        }

        public static final Creator<SavedState> CREATOR = new Creator<SavedState>() {
            @Override
            public SavedState createFromParcel(Parcel in) {
                return new SavedState(in);
            }

            @Override
            public SavedState[] newArray(int size) {
                return new SavedState[size];
            }
        };
    }
}
